﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using NodeBasedSkillEditor.Model.CommandHistory;
using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Media;

namespace NodeBasedSkillEditor.ViewModel
{
    public class VM_MainWindow : ObservableObject
    {
        public static VM_MainWindow Instance { get; private set; }

        private string _title;
        public string Title {
            get { return _title; }
            set { _title = value; OnPropertyChanged(); }
        }

        private string _currWorkingFilePath;
        public string CurrWorkingFilePath {
            get { return _currWorkingFilePath; }
            set {
                _currWorkingFilePath = value;
                OnPropertyChanged();
                UpdateCurrWorkingFolder();
            }
        }
        private SolidColorBrush mWorkingFileBorderColor = new SolidColorBrush(Colors.LightGray);
        public SolidColorBrush WorkingFileBorderColor {
            get { return mWorkingFileBorderColor; }
            set { mWorkingFileBorderColor = value; OnPropertyChanged(); }
        }


        private string _currWorkingFolder;
        public string CurrWorkingFolder {
            get { return _currWorkingFolder; }
            set { _currWorkingFolder = value; OnPropertyChanged(); }
        }
        void UpdateCurrWorkingFolder()
        {
            CurrWorkingFolder = Environment.CurrentDirectory;
            if (!string.IsNullOrEmpty(CurrWorkingFilePath))
            {
                var dir = Path.GetDirectoryName(CurrWorkingFilePath);
                if (Directory.Exists(dir))
                {
                    CurrWorkingFolder = dir;
                }
            }
        }

        private string _consoleString;
        public string ConsoleString {
            get { return _consoleString; }
            set { _consoleString = value; OnPropertyChanged(); }
        }
        StringBuilder _consoleText = new StringBuilder();

        private VM_DAG _dagVM = new VM_DAG();
        public VM_DAG DagVM {
            get { return _dagVM; }
            set { _dagVM = value; OnPropertyChanged(); }
        }

        public RelayCommand NewFileCmd { get; set; }
        public RelayCommand OpenFileCmd { get; set; }
        public RelayCommand OpenFileWithoutDecompressCmd { get; set; }
        public RelayCommand SaveFileCmd { get; set; }
        public RelayCommand SaveFileWithoutCompressCmd { get; set; }
        public RelayCommand SaveAsFileCmd { get; set; }
        public RelayCommand FocusFilterCmd { get; set; }
        public RelayCommand UndoCmd { get; set; }
        public RelayCommand RedoCmd { get; set; }

        //CommandHistory _cmdHistory = new CommandHistory();
        //private UndoManager _undoManager;
        private string _version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

        public event Action OnFocusFilterBox;

        public VM_MainWindow()
        {
            Instance = this;

            Title = "Node Based Skill Editor " + _version;

            NewFileCmd = new RelayCommand(NewFile);
            OpenFileCmd = new RelayCommand(OpenFile);
            OpenFileWithoutDecompressCmd = new RelayCommand(OpenFileWithoutDecompress);
            SaveFileCmd = new RelayCommand(SaveFile);
            SaveFileWithoutCompressCmd = new RelayCommand(SaveFileWithoutCompress);
            SaveAsFileCmd = new RelayCommand(SaveAsFile);

            FocusFilterCmd = new RelayCommand(FocusFilter);

            UndoCmd = new RelayCommand(Undo);
            RedoCmd = new RelayCommand(Redo);

            DagVM.OnAddCommandRecord += AddRecordToHistory;
            DagVM.RegisterCommandHistoryHandlers();

            //_undoManager = new UndoManager(this);
        }

        void NewFile()
        {
            CurrWorkingFilePath = "";
            DagVM.ClearAll();
            //_undoManager.Clear();
            UndoManager.Instance.ClearHistroy();
            WorkingFileBorderColor.Color = Colors.LightGray;
        }

        void OpenFile()
        {
            OpenFile(true);
        }

        void OpenFileWithoutDecompress()
        {
            OpenFile(false);
        }

        void OpenFile(bool decompress)
        {
            var dlg = new OpenFileDialog();

            dlg.Title = "Open Skill File";
            dlg.InitialDirectory = CurrWorkingFolder;
            dlg.DefaultExt = ".skill";
            dlg.Filter = "Skill Files (*.skill)|*.skill";

            bool? result = dlg.ShowDialog();

            if (result == true)
            {
                CurrWorkingFilePath = dlg.FileName;
                DagVM.ReadDAGFile(CurrWorkingFilePath, decompress);
                //_undoManager.Clear();
                UndoManager.Instance.ClearHistroy();
                WorkingFileBorderColor.Color = Colors.LightGray;
            }
        }

        void SaveFile()
        {
            SaveFile(true);
            WorkingFileBorderColor.Color = Colors.LightGray;
        }

        void SaveFile(bool compress)
        {
            if (File.Exists(CurrWorkingFilePath))
            {
                DagVM.SaveCurrentDAGToFile(CurrWorkingFilePath, compress);
            }
            else
            {
                SaveAsFile(compress);
            }
        }

        void SaveAsFile()
        {
            SaveAsFile(true);
        }

        void SaveFileWithoutCompress()
        {
            SaveAsFile(false);
        }

        void SaveAsFile(bool compress)
        {
            var dlg = new SaveFileDialog();

            dlg.Title = "Save as";
            dlg.InitialDirectory = CurrWorkingFolder;
            dlg.DefaultExt = ".skill";
            dlg.Filter = "Skill Files (*.skill)|*.skill";

            var result = dlg.ShowDialog();

            if (result.HasValue && result == true)
            {
                var savePath = dlg.FileName;
                DagVM.SaveCurrentDAGToFile(savePath, compress);
                CurrWorkingFilePath = savePath;
            }
        }

        void FocusFilter()
        {
            OnFocusFilterBox?.Invoke();
        }

        void AddRecordToHistory(CommandRecord cmdRec)
        {
            //_undoManager.AddRecord(cmdRec);
            UndoManager.Instance.AddRecord(cmdRec);
            WorkingFileBorderColor.Color = Colors.Red;
        }

        void Undo()
        {
            UndoManager.Instance.Undo();
            //_undoManager.Undo();
        }

        void Redo()
        {
            UndoManager.Instance.Redo();
            //_undoManager.Redo();
        }

        public void AppenToConsole(string line)
        {
            ConsoleString = line;
            //_consoleText.AppendLine(line);
            //ConsoleString = _consoleText.ToString();
        }
    }
}
